package com.ergou.easylive.admin.service.impl;

import com.ergou.easylive.admin.convert.SysUserRegisterDTOConverter;
import com.ergou.easylive.admin.entity.bo.SysUserRegisterBO;
import com.ergou.easylive.admin.entity.dto.SysLoginDTO;
import com.ergou.easylive.admin.entity.po.SysUser;
import com.ergou.easylive.admin.mapper.SysUserMapper;
import com.ergou.easylive.admin.service.SysUserService;
import com.ergou.easylive.admin.util.AvatarUtil;
import com.ergou.easylive.admin.util.JwtUtil;
import com.ergou.easylive.common.enums.ResultCode;
import com.ergou.easylive.common.util.PasswordEncoder;
import com.ergou.easylive.admin.exception.AuthException;
import com.ergou.easylive.admin.exception.SystemException;
import com.ergou.easylive.admin.exception.UserException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * 系统用户(SysUser)服务实现类
 *
 * @author Er-Gou
 * @date 2025-09-22 20:17
 */
@Service
@Slf4j
public class SysUserServiceImpl implements SysUserService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private JwtUtil jwtUtil;

    @Resource
    private CacheManager cacheManager;

    @Resource
    private HttpServletRequest request;


    // 用户注册
    @Override
    public void register(SysUserRegisterBO sysUserRegisterBO) {
        // 校验用户信息
        validate(sysUserRegisterBO);
        SysUser sysUser = SysUserRegisterDTOConverter.INSTANCE.convertBOToEntity(sysUserRegisterBO);
        String randomAvatar = AvatarUtil.getRandomAvatar();
        sysUser.setAvatar(randomAvatar);
        sysUser.setNickname("新用户-" + UUID.randomUUID());
        sysUser.setCreateTime(LocalDateTime.now());
        sysUser.setUpdateTime(LocalDateTime.now());
        // 将密码加密
        String encode = PasswordEncoder.encode(sysUser.getPassword());
        sysUser.setPassword(encode);
        sysUserMapper.insert(sysUser);
    }


    // 用户登录
    @Override
    public String login(SysLoginDTO sysLoginDTO) {
        // 1. 校验验证码
        validateCaptcha(sysLoginDTO.getUuid(), sysLoginDTO.getCode());

        // 2. 根据用户名查询用户
        SysUser sysUser = sysUserMapper.selectByUsername(sysLoginDTO.getUsername());
        if (sysUser == null) {
            throw new UserException(ResultCode.USER_NOT_EXIST);
        }

        // 3. 校验密码
        boolean passwordMatch = PasswordEncoder.matches(sysLoginDTO.getPassword(), sysUser.getPassword());
        if (!passwordMatch) {
            throw new AuthException(ResultCode.LOGIN_FAILED);
        }

        // 4. 检查用户状态
        if (sysUser.getStatus() == 0) {
            throw new UserException(ResultCode.FORBIDDEN, "用户已被禁用");
        }

        // 5. 更新最后登录时间
        updateLastLoginTime(sysUser);

        // 6. 生成JWT Token
        String token = jwtUtil.generateToken(sysUser.getId().toString(), sysUser.getUsername());

        return token;
    }

    /**
     * 校验验证码
     *
     * @param uuid 验证码UUID
     * @param code 验证码
     */
    private void validateCaptcha(String uuid, String code) {
        // 从缓存中获取验证码
        Cache cache = cacheManager.getCache("captcha");
        if (cache == null) {
            throw new SystemException(ResultCode.SERVICE_UNAVAILABLE, "验证码缓存未配置");
        }

        String cacheKey = "sys_captcha_code_key:" + uuid;
        String cachedCode = cache.get(cacheKey, String.class);

        if (StringUtils.isEmpty(cachedCode)) {
            throw new AuthException(ResultCode.BAD_REQUEST, "验证码已过期");
        }

        if (!cachedCode.equalsIgnoreCase(code)) {
            throw new AuthException(ResultCode.BAD_REQUEST, "验证码错误");
        }

        // 验证成功后删除验证码
        cache.evict(cacheKey);
    }

    /**
     * 更新最后登录时间
     *
     * @param sysUser 用户信息
     */
    private void updateLastLoginTime(SysUser sysUser) {
        try {
            sysUser.setLastLoginTime(LocalDateTime.now());
            sysUser.setLastLoginIp(getClientIp());
            sysUser.setUpdateTime(LocalDateTime.now());
            sysUserMapper.updateById(sysUser);
        } catch (Exception e) {
            log.warn("更新用户登录时间失败: {}", e.getMessage());
        }
    }

    /**
     * 获取客户端IP地址
     *
     * @return IP地址
     */
    private String getClientIp() {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 校验用户信息
     *
     * @param sysUserRegisterBO
     */
    private void validate(SysUserRegisterBO sysUserRegisterBO) {
        String username = sysUserRegisterBO.getUsername();
        String password = sysUserRegisterBO.getPassword();

        if (StringUtils.isEmpty(username)) {
            throw new UserException(ResultCode.BAD_REQUEST, "用户名不能为空");
        }
        if (StringUtils.isEmpty(password)) {
            throw new UserException(ResultCode.BAD_REQUEST, "密码不能为空");
        }
    }

    @Override
    public SysUser getUserByUsername(String username) {
        return sysUserMapper.selectByUsername(username);
    }
}
